package com.data.practice.queue;

import java.util.Scanner;

public class CircleArrayQueueDemo {

	public static void main(String[] args) {
		
		//???????
		System.out.println("环形队列的模拟");
		
		// 创建环形队列
		CircleArray queue = new CircleArray(4);
		//用来接受用户输入的数据
		char key = ' '; // ???????????
		Scanner scanner = new Scanner(System.in);//
		boolean loop = true;
		// ?????????
		while (loop) {
			System.out.println("s(show)  显示队列");
			System.out.println("e(exit)  退出程序");
			System.out.println("a(add)  添加数据到队列");
			System.out.println("g(get)  从队列取出数据");
			System.out.println("h(head) 查出队列头的信息");
			key = scanner.next().charAt(0);// 得到用户输入的数据
			switch (key) {
			case 's':
				queue.showQueue();
				break;
			case 'a':
				System.out.println("前输入入队数据");
				int value = scanner.nextInt();
				queue.addQueue(value);
				break;
			case 'g': //出队
				try {
					int res = queue.getQueue();
					System.out.printf("出队数据：%d\n", res);
				} catch (Exception e) {
					// TODO: handle exception
					System.out.println(e.getMessage());
				}
				break;
			case 'h': // 得到头元素
				try {
					int res = queue.headQueue();
					System.out.printf("出队头元素%d\n", res);
				} catch (Exception e) {
					// TODO: handle exception
					System.out.println(e.getMessage());
				}
				break;
			case 'e': // ???
				scanner.close();
				loop = false;
				break;
			default:
				break;
			}
		}
		System.out.println("程序退出");
	}

}


class CircleArray {
	private int maxSize; //数组的最大容量
	private int front; 
	//队列的头 指向第一个元素 初始化赋值为0
	//rear 队尾元素 指向最后一个元素的后一位
	private int rear; // 默认值为0
	private int[] arr; // 循环队列
	
	public CircleArray(int arrMaxSize) {
		maxSize = arrMaxSize;
		arr = new int[maxSize];
	}
	
	// 判断队列是否满了
	public boolean isFull() {
		return (rear + 1) % maxSize == front;
	}
	
	// 判断队列是否为空
	public boolean isEmpty() {
		return rear == front;
	}
	
	// 向队列添加数据
	public void addQueue(int n) {
		// 判断队列是否满了
		if (isFull()) {
			System.out.println("队列已满，不能添加数据");
			return;
		}
		arr[rear] = n;
		//队尾向后移一位
		rear = (rear + 1) % maxSize;
	}
	
	// 出队
	public int getQueue() {
		// 判断队列是否为空
		if (isEmpty()) {
			// 抛出异常
			throw new RuntimeException("队列为空，不能出队");
		}
		// 对头元素出队
		//
		int value = arr[front];
		front = (front + 1) % maxSize;
		return value;
	}
	
	// 显示队列的所有数据
	public void showQueue() {
		// 队列是否为空
		if (isEmpty()) {
			System.out.println("队列是否为空");
			return;
		}
		// 思路：：队列的有效数据  （rear+maxsize-front）%maxsize=有效数据个数）
		//  i%maxSize
		for (int i = front; i < front + size() ; i++) {
			System.out.printf("arr[%d]=%d\n", i % maxSize, arr[i % maxSize]);
		}
	}
	
	// 队列的有效数据::(rear+maxsize-front)%maxsize=有效数据个数)
	public int size() {
		// rear = 2
		// front = 1
		// maxSize = 3 
		return (rear + maxSize - front) % maxSize;   
	}
	
	// 显示头元素
	public int headQueue() {
		// 判断是否为空
		if (isEmpty()) {
			throw new RuntimeException("队列元素为空");
		}
		return arr[front];
	}
	
}